<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>策略模式</title>
</head>

<body>
    <script>
        /*
        策略模式
        +一个问题匹配多个解决方案，不一定用到哪一个
        +而且有可能虽是海水继续增加多个方案
        +例子：购物结算
         =>我们有好多中折扣计算方式
         =>满100减10
         =>满200减25
         =>打8折
         =>打7折
         1.把我们的多种方案，以闭包的的形式，保存起来
            +对外留一个接口，可以添加和减少
            +按照传进来的折扣和价格计算最终价格返回
         2.留下添加折扣和删除折扣的接口
            +函数也是一个对象
            +可以把函数名当做一个对象，向里面添加一些成员
         
        */

        //2.添加一节接口(向对象里面添加一些成员)

        const calcPrice = (function (params) {
            const sale = {
                '100-10': function (price) { return price -= 10 },
                '200-25': function (price) { return price -= 25 },
                '80%': function (price) { return price *= 0.8 },
            }
            //被return出去的函数，才是calcPrice本体


            function calcPrice(price, type) {
                // 在这判断对象里面有没有这个折扣类型
                // 如果有就执行
                // 如果没有，就告诉他没有这个折扣类型
                if (!sale[type]) return '没有这个折扣！！！'

                // 找到sale里面指定的那个函数，执行计算出结果，返回给外边

                return sale[type](price)
            }
            // 把函数当做一个对象，向里面添加一些成员
            calcPrice.add = function (type, fn) {
                // 专门用来添加一些折扣方案
                // 1.判断折扣是否存在
                // console.log(sale[type]);
                if (sale[type]) return '该折扣已经存在'
                // 代码来到这里，表示折扣不存在，
                // 那么就把这个成员（方案），添加到对象里面去
                sale[type] = fn
            }
            calcPrice.del = function (type, fn) {
                // 把对应的折扣删除掉
                delete sale[type]
            }
            return calcPrice
        })()

        // const res = calcPrice(320, '100-10')
        // 使用的时候添加一个折扣
        // const res = calcPrice.add('90%', function (price) { return price *= 0.9 })
        // console.dir(res);
        calcPrice.add('90%', function (price) { return price *= 0.9 })
        const res = calcPrice(320, '90%')
        console.dir(res);
        // console.dir(calcPrice);
        calcPrice.del('100-10')
        const res2 = calcPrice(320, '100-10')
        console.log(res2);

        // 1.暂时以闭包的形式把折扣方案保存下来
        // const calcPrice = (function (params) {
        //     const sale = {
        //         '100-10': function (price) { return price -= 10 },
        //         '200-25': function (price) { return price -= 25 },
        //         '0.8': function (price) { return price *= 0.8 },
        //     }
        //     //被return出去的函数，才是calcPrice本体
        //     return function calcPrice(price, type) {
        //         // 在这判断对象里面有没有这个折扣类型
        //         // 如果有就执行
        //         // 如果没有，就告诉他没有这个折扣类型
        //         if (!sale[type]) return '没有这个折扣！！！'

        //         // 找到sale里面指定的那个函数，执行计算出结果，返回给外边

        //         return sale[type](price)
        //     }
        // })()

        // const res = calcPrice(320, '100-10')
        // console.log(res);

        // 0.最简单简易的实现方式
        //    接收两个参数，价格，折扣种类
        //    虽然下面的写法已经满足了几种折扣方案的需求，
        //    但是一旦加一种折扣,要改动代码，如果其中一种方案不需要了，又要删代码,
        // function calcPrice(price, type) {
        //     if (type === '100-10') {
        //         price -= 10//满100-10
        //     } else if (type === '200-25') {
        //         price -= 25//满200-25
        //     } else if (type === '80%') {
        //         price *= 0.8//打八折
        //     } else {
        //         console.log('没有这种折扣');
        //     }
        //     return price
        // }
        // 将来使用的时候
        // const res = calcPrice(320, '200-25')
        // console.log(res)
    </script>
</body>

</html>